/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg1;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

/**
 * This class Contains the mother of all information
 * Keeps track of entire system, what important windows are open,
 * and what floors and templates are in use.
 * @author Nick
 */
public class Context {
    
    private static ArrayList<Doctor> doctors = new ArrayList<Doctor>();
    private static ArrayList<Nurse> nurses = new ArrayList<Nurse>();
    private static Context context;
    private static ArrayList<FloorContext> floors = new ArrayList<FloorContext>();
    private static ArrayList<FloorTemplateData> templates = new ArrayList<FloorTemplateData>();
    private static ArrayList<Window> windows = new ArrayList<Window>();
    
    /**
     * private constructor
     */
    private Context() {
        
    }
    
    //Access to the singleton
    public static synchronized Context getContext() {
        if(context == null) {
            context = new Context();
        }
        return context;
    }
    
    // returns active windows that may require saving
    public Iterator<Window> getWindows() {
        ArrayList<Window> e = (ArrayList<Window>)windows.clone();
        return e.iterator();
    }
    
    // adds a window
    public void addWindow(Window window) {
        windows.add(window);
    }
    
    // removes a window
    public void removeWindow(Window window) {
        windows.remove(window);
    }
    
    /**
     * no Cloning my singleton!
     * @return exception lol
     * @throws CloneNotSupportedException 
     */
    public Object clone() throws CloneNotSupportedException
    {
        throw new CloneNotSupportedException(); 
    // that'll teach 'em
    }
    
    //adds a floor
    public void addFloor(FloorContext fc) {
        floors.add(fc);
    }
    
    //removes a floor
    public void removeFloor(String id) {
        for(FloorContext floor : floors) {
            if(floor.getId().equals(id)) {
                floors.remove(floor);
                return;
            }
        }
    }
    
    //gets all the floors in the currently loaded in
    public ArrayList<FloorContext> getFloors() {
        return floors;
    }
    
    //gets a loaded floor based on its id
    public static FloorContext getFloor(String id) {
        for(FloorContext fc : floors) {
            if(fc.getId().equals(id)) {
                return fc;
            }
        }
        return null;
    }
    
    //returns whether a given floor name is taken
    public boolean isValidNewFloorName(String newFloorName) {
        for(FloorContext fc : floors) {
            if(fc.getId().equals(newFloorName)) {
                return false;
            }
        }
        return true;
    }
    
    //returns whether a given template name is loaded
    public boolean isValidTemplateName(String newTemplateName) {
        for(FloorTemplateData templateData : templates) {
            if(templateData.getId().equals(newTemplateName)) {
                return false;
            }
        }
        return true;
    }
    
    //gets the floor of the bed.
    public FloorContext getFloor(Bed b) {
        for(FloorContext context : floors) {
            if(context.getBeds().contains(b)) {
                return context;
            }
        }
        return null;
    }
    
    // gets the floor object from the mother
    public FloorContext getFloor(FloorContext floor) {
        for(FloorContext fc : floors) {
            if(fc.equals(floor)) {
                return fc;
            }
        }
        return null;
    }
    
     /**
     * gets the nurses
     * @return the nurses
     */
    public ArrayList<Nurse> getNurses() {
        return nurses;
    }
    
     /**
     * gets the doctors
     * @return  doctors
     */
    public ArrayList<Doctor> getDoctors() {
        return doctors;
    }
    
    /**
     * returns a random doctor
     * @return 
     */
    public Doctor getRandomDoctor() {
        Random gen = new Random();
        int randomInt = gen.nextInt(doctors.size());
        return doctors.get(randomInt);
    }
    
    /**
     * returns a random nurse
     * @return 
     */
    public Nurse getRandomNurse() {
        Random gen = new Random();
        int randomInt = gen.nextInt(nurses.size());
        return nurses.get(randomInt);
    }
    
    /**
     * returns all active templates
     * @return 
     */
    public ArrayList<FloorTemplateData> getTemplates() {
        return templates;
    }
    
    /**
     * adds a template
     * @param template 
     */
    public void addTemplate(FloorTemplateData template) {
        templates.add(template);
    }
    
    /**
     * returns all active beds
     * @return 
     */
    public ArrayList<Bed> getBeds() {
        ArrayList<Bed> tmp = new ArrayList<Bed>();
        for(FloorContext floor : floors) {
            tmp.addAll(floor.getBeds());
        }
        return tmp;
    }
    
    /**
     * removes a patient from their doctor and nurse
     * @param pat 
     */
    public void removePatientFromDoctorAndNurseIfAlreadyExist(Patient pat) {
        for(Doctor doctor : doctors) {
            for(Patient p : doctor.getPatients()) {
                if(p.getId() == pat.getId() && p.getDateOfAdmissions() == pat.getDateOfAdmissions()) {
                    doctor.getPatients().remove(p);
                    break;
                }
            }
        }
        for(Nurse nurse : nurses) {
            for(Patient p : nurse.getPatients()) {
                if(p.getId() == pat.getId() && p.getDateOfAdmissions() == pat.getDateOfAdmissions()) {
                    nurse.getPatients().remove(p);
                    break;
                }
            }
        }
    }
}
